import subprocess
import os
import sys
import json
from pathlib import Path
from typing import List, Dict, Optional
from tqdm import tqdm


def fetch_file_contents(base_repo_dir: str,
                        entries: List[Dict[str, str]],
                        encoding: str = 'utf-8') -> List[Dict]:
    """
    从本地Git仓库获取指定提交版本的文件内容
    
    :param base_repo_dir: 本地Git仓库存储的根目录
    :param entries: 包含查询参数的字典列表，每个字典需包含：
                   - repo: 仓库目录名（相对于base_repo_dir）
                   - commit: 完整的提交哈希值
                   - file: 仓库内文件路径（相对路径）
    :param encoding: 文件编码格式（默认utf-8）
    :return: 包含结果和错误信息的字典列表
    """
    results = []

    # for entry in entries:
    for entry in tqdm(entries, desc="checkout"):
        repo = entry['repo']
        commit = entry['commit']
        file_path = entry['file']
        result_template = {
            'repo': repo,
            'commit': commit,
            'file': file_path,
            'content': None,
            'error': None
        }

        print(f'正在处理: repo:{repo}  commit:{commit}')

        try:
            # 验证仓库路径
            repo_full_path = Path(base_repo_dir) / repo
            if not (repo_full_path.exists() and (repo_full_path / '.git').is_dir()):
                raise ValueError(f"Invalid git repository: {repo_full_path}")

            # 强制切换到目标提交
            checkout_process = subprocess.run(
                ['git', 'checkout', '--force', commit],
                cwd=repo_full_path,
                capture_output=True,
                text=True,
                timeout=30  # 防止长时间无响应
            )

            if checkout_process.returncode != 0:
                raise RuntimeError(
                    f"Checkout failed: {checkout_process.stderr.strip()}"
                )

            # 读取文件内容
            target_file = repo_full_path / file_path
            if not target_file.exists():
                raise FileNotFoundError(
                    f"File not found in repository: {file_path}"
                )

            content = target_file.read_text(encoding=encoding)
            result_template['content'] = content

        except Exception as e:
            result_template['error'] = str(e)

        results.append(result_template)

    return results


# 示例用法
if __name__ == "__main__":
    BASE_DIR = r"D:\JunTuan\project\py_test\swebench使用\swe-bench-verified\repos\gitrepos"  # 替换为实际仓库根目录
    with open("公开评测集_SWE-bench-lite.json", encoding="utf-8") as f:
        flines = f.readlines()
    TEST_ENTRIES = []
    for iline in flines:
        ijson = json.loads(iline)
        TEST_ENTRIES.append(
            {"repo": ijson["repo"].split("/")[1], "commit": ijson["base_commit"], "file": ijson["patch"].split("\n")[0].split(" b/")[1]})

    # 执行获取操作
    results = fetch_file_contents(BASE_DIR, TEST_ENTRIES)

    outdir = "commit_target"
    os.makedirs(outdir, exist_ok=True)
    for idx, result in enumerate(results):
        content = result['error'] if result['error'] else result['content']
        with open(os.path.join(outdir, f"{idx}.py"), "w+", encoding="utf-8") as f: f.write(content)
